{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Tce3stUlHN0L"
      },
      "source": [
        "##### Copyright 2025 Google LLC."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "cellView": "form",
        "id": "tuOe1ymfHZPu"
      },
      "outputs": [],
      "source": [
        "# @title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yeadDkMiISin"
      },
      "source": [
        "# Gemini API: Authentication Quickstart"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lEXQ3OwKIa-O"
      },
      "source": [
        "<a target=\"_blank\" href=\"https://colab.research.google.com/github/google-gemini/cookbook/blob/main/quickstarts/Authentication.ipynb\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" height=30/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "df1767a3d1cc"
      },
      "source": [
        "The Gemini API uses API keys for authentication. This notebook walks you through creating an API key, and using it with the Python SDK or a command-line tool like `curl`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mhFKmRmxi5B-"
      },
      "source": [
        "## Create an API key\n",
        "\n",
        "You can [create](https://aistudio.google.com/app/apikey) your API key using Google AI Studio with a single click.  \n",
        "\n",
        "Remember to treat your API key like a password. Don't accidentally save it in a notebook or source file you later commit to GitHub. This notebook shows you two ways you can securely store your API key.\n",
        "\n",
        "* If you're using Google Colab, it's recommended to store your key in Colab Secrets.\n",
        "\n",
        "* If you're using a different development environment (or calling the Gemini API through `cURL` in your terminal), it's recommended to store your key in an [environment variable](https://en.wikipedia.org/wiki/Environment_variable).\n",
        "\n",
        "Let's start with Colab Secrets."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dEoigYI9Jw_K"
      },
      "source": [
        "## Add your key to Colab Secrets\n",
        "\n",
        "Add your API key to the Colab Secrets manager to securely store it.\n",
        "\n",
        "1. Open your Google Colab notebook and click on the 🔑 **Secrets** tab in the left panel.\n",
        "   \n",
        "   <img src=\"https://storage.googleapis.com/generativeai-downloads/images/secrets.jpg\" alt=\"You can find the Secrets tab on the left panel.\" width=50%>\n",
        "\n",
        "2. Create a new secret with the name `GOOGLE_API_KEY`.\n",
        "3. Copy and paste your API key into the `Value` input box of `GOOGLE_API_KEY`.\n",
        "4. Toggle the button on the left to allow all notebooks access to the secret.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jRY1eioF4gUB"
      },
      "source": [
        "## Install the Python SDK"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "xuiLSV7amy3P"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\u001b[?25l   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/200.0 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\n",
            "\u001b[2K   \u001b[91m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[91m╸\u001b[0m\u001b[90m━\u001b[0m \u001b[32m194.6/200.0 kB\u001b[0m \u001b[31m29.4 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\r\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m200.0/200.0 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25h"
          ]
        }
      ],
      "source": [
        "%pip install -qU 'google-genai>=1.0.0'"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3dw8ygh74mVc"
      },
      "source": [
        "## Configure the SDK with your API key\n",
        "\n",
        "You create a client using your API key, but instead of pasting your key into the notebook, you'll read it from Colab Secrets thanks to `userdata`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "id": "DTl-qZp34sht"
      },
      "outputs": [],
      "source": [
        "from google import genai\n",
        "from google.colab import userdata\n",
        "\n",
        "GOOGLE_API_KEY = userdata.get('GOOGLE_API_KEY')\n",
        "client = genai.Client(api_key=GOOGLE_API_KEY)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b7ceb7517bf5"
      },
      "source": [
        "Now choose a model. The Gemini API offers different models that are optimized for specific use cases. For more information check [Gemini models](https://ai.google.dev/gemini-api/docs/models)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "7135d9ae3e4b"
      },
      "outputs": [],
      "source": [
        "MODEL_ID = \"gemini-2.5-flash\" # @param [\"gemini-2.5-flash-lite\", \"gemini-2.5-flash\", \"gemini-2.5-pro\",\"gemini-3-pro-preview\"] {\"allow-input\":true, isTemplate: true}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tr7oAO6-nMsE"
      },
      "source": [
        "And that's it! Now you're ready to call the Gemini API."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "n6sXnWrJoKoo"
      },
      "outputs": [
        {
          "data": {
            "text/markdown": [
              "Python provides incredibly convenient and efficient ways to sort lists. There are two primary built-in functions you'll use:\n",
              "\n",
              "1.  **`list.sort()`**: This method sorts the list *in-place*, meaning it modifies the original list and doesn't return a new one. It returns `None`.\n",
              "2.  **`sorted()`**: This built-in function returns a *new* sorted list, leaving the original list unchanged. It can be used on any iterable (lists, tuples, strings, etc.).\n",
              "\n",
              "Let's look at examples for both.\n",
              "\n",
              "---\n",
              "\n",
              "### 1. Using `list.sort()` (Sorts In-Place)\n",
              "\n",
              "This is suitable when you don't need to preserve the original order of the list.\n",
              "\n",
              "```python\n",
              "# --- Basic Sorting (Ascending) ---\n",
              "my_numbers = [3, 1, 4, 1, 5, 9, 2, 6]\n",
              "my_numbers.sort() # Modifies my_numbers directly\n",
              "print(\"Sorted numbers (in-place):\", my_numbers) # Output: [1, 1, 2, 3, 4, 5, 6, 9]\n",
              "\n",
              "my_strings = [\"banana\", \"apple\", \"cherry\", \"date\"]\n",
              "my_strings.sort()\n",
              "print(\"Sorted strings (in-place):\", my_strings) # Output: ['apple', 'banana', 'cherry', 'date']\n",
              "\n",
              "# --- Sorting in Descending Order (reverse=True) ---\n",
              "my_numbers = [3, 1, 4, 1, 5, 9, 2, 6]\n",
              "my_numbers.sort(reverse=True)\n",
              "print(\"Sorted numbers (descending, in-place):\", my_numbers) # Output: [9, 6, 5, 4, 3, 2, 1, 1]\n",
              "\n",
              "# --- Sorting with a Custom Key (e.g., by length of strings) ---\n",
              "words = [\"apple\", \"banana\", \"kiwi\", \"grapefruit\", \"cat\"]\n",
              "words.sort(key=len) # Sorts by the length of each string\n",
              "print(\"Sorted by length (in-place):\", words) # Output: ['cat', 'kiwi', 'apple', 'banana', 'grapefruit']\n",
              "\n",
              "# --- Sorting Case-Insensitively (for strings) ---\n",
              "names = [\"Alice\", \"bob\", \"Charlie\", \"David\", \"frank\"]\n",
              "names.sort(key=str.lower) # Converts each string to lowercase for comparison\n",
              "print(\"Sorted case-insensitively (in-place):\", names) # Output: ['Alice', 'bob', 'Charlie', 'David', 'frank']\n",
              "\n",
              "# --- Sorting a list of dictionaries by a specific value ---\n",
              "people = [\n",
              "    {\"name\": \"Alice\", \"age\": 30},\n",
              "    {\"name\": \"Bob\", \"age\": 25},\n",
              "    {\"name\": \"Charlie\", \"age\": 35},\n",
              "    {\"name\": \"David\", \"age\": 25} # David and Bob have same age\n",
              "]\n",
              "people.sort(key=lambda person: person[\"age\"]) # Sorts by the 'age' value\n",
              "print(\"Sorted people by age (in-place):\", people)\n",
              "# Output: [{'name': 'Bob', 'age': 25}, {'name': 'David', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]\n",
              "# Note: The original relative order of Bob and David (same age) is preserved because Python's sort is stable.\n",
              "```\n",
              "\n",
              "---\n",
              "\n",
              "### 2. Using `sorted()` (Returns a New Sorted List)\n",
              "\n",
              "This is preferred when you want to keep the original list intact.\n",
              "\n",
              "```python\n",
              "# --- Basic Sorting (Ascending) ---\n",
              "original_numbers = [3, 1, 4, 1, 5, 9, 2, 6]\n",
              "sorted_numbers = sorted(original_numbers) # Creates a new list\n",
              "print(\"Original numbers:\", original_numbers) # Output: [3, 1, 4, 1, 5, 9, 2, 6] (unchanged)\n",
              "print(\"New sorted numbers:\", sorted_numbers) # Output: [1, 1, 2, 3, 4, 5, 6, 9]\n",
              "\n",
              "original_strings = [\"banana\", \"apple\", \"cherry\", \"date\"]\n",
              "new_sorted_strings = sorted(original_strings)\n",
              "print(\"Original strings:\", original_strings) # Output: ['banana', 'apple', 'cherry', 'date']\n",
              "print(\"New sorted strings:\", new_sorted_strings) # Output: ['apple', 'banana', 'cherry', 'date']\n",
              "\n",
              "# --- Sorting in Descending Order (reverse=True) ---\n",
              "data = [10, 5, 8, 2, 12]\n",
              "descending_data = sorted(data, reverse=True)\n",
              "print(\"New sorted data (descending):\", descending_data) # Output: [12, 10, 8, 5, 2]\n",
              "\n",
              "# --- Sorting with a Custom Key (e.g., by length of strings) ---\n",
              "fruits = [\"strawberry\", \"pear\", \"blueberry\", \"kiwi\"]\n",
              "sorted_by_length = sorted(fruits, key=len)\n",
              "print(\"New sorted fruits by length:\", sorted_by_length) # Output: ['pear', 'kiwi', 'strawberry', 'blueberry']\n",
              "\n",
              "# --- Sorting Case-Insensitively (for strings) ---\n",
              "countries = [\"USA\", \"canada\", \"Mexico\", \"france\"]\n",
              "sorted_countries = sorted(countries, key=str.lower)\n",
              "print(\"New sorted countries (case-insensitive):\", sorted_countries) # Output: ['canada', 'france', 'Mexico', 'USA']\n",
              "\n",
              "# --- Sorting a list of dictionaries by a specific value ---\n",
              "students = [\n",
              "    {\"name\": \"Zoe\", \"score\": 85},\n",
              "    {\"name\": \"Alex\", \"score\": 92},\n",
              "    {\"name\": \"Chris\", \"score\": 78},\n",
              "    {\"name\": \"Ben\", \"score\": 92} # Alex and Ben have same score\n",
              "]\n",
              "sorted_students = sorted(students, key=lambda student: student[\"score\"])\n",
              "print(\"New sorted students by score:\", sorted_students)\n",
              "# Output: [{'name': 'Chris', 'score': 78}, {'name': 'Zoe', 'score': 85}, {'name': 'Alex', 'score': 92}, {'name': 'Ben', 'score': 92}]\n",
              "# Again, Python's sort is stable, preserving Alex's and Ben's original relative order.\n",
              "\n",
              "# --- Sorting a list of tuples (default is lexicographical) ---\n",
              "points = [(1, 5), (3, 2), (1, 2), (2, 4)]\n",
              "sorted_points = sorted(points) # Sorts primarily by the first element, then the second\n",
              "print(\"Sorted points (lexicographical):\", sorted_points) # Output: [(1, 2), (1, 5), (2, 4), (3, 2)]\n",
              "\n",
              "# --- Sorting a list of tuples by the second element ---\n",
              "sorted_points_by_y = sorted(points, key=lambda p: p[1])\n",
              "print(\"Sorted points by Y-coordinate:\", sorted_points_by_y) # Output: [(3, 2), (1, 2), (2, 4), (1, 5)]\n",
              "```\n",
              "\n",
              "---\n",
              "\n",
              "### When to use which:\n",
              "\n",
              "*   Use **`list.sort()`** if you *don't need the original list* and want to save memory by modifying it in place.\n",
              "*   Use **`sorted()`** if you *need to preserve the original list* or if you are sorting an iterable that isn't a list (like a tuple, string, or set).\n",
              "\n",
              "Both methods are very efficient, leveraging Python's highly optimized **Timsort** algorithm."
            ],
            "text/plain": [
              "<IPython.core.display.Markdown object>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "from IPython.display import Markdown\n",
        "\n",
        "response = client.models.generate_content(\n",
        "    model=MODEL_ID,\n",
        "    contents=\"Please give me python code to sort a list.\"\n",
        ")\n",
        "\n",
        "display(Markdown(response.text))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BTdQtZri1Brs"
      },
      "source": [
        "## Store your key in an environment variable"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gZDX51Y27pN4"
      },
      "source": [
        "If you're using a different development environment (or calling the Gemini API through `cURL` in your terminal), it's recommended to store your key in an environment variable.\n",
        "\n",
        "To store your key in an environment variable, open your terminal and run:\n",
        "\n",
        "```export GOOGLE_API_KEY=\"YOUR_API_KEY\"```\n",
        "\n",
        "If you're using Python, you can add these two lines to your notebook to read the key:\n",
        "\n",
        "```\n",
        "import os\n",
        "client = genai.Client(api_key=os.environ['GOOGLE_API_KEY'])\n",
        "```\n",
        "\n",
        "Alternatively, if it isn't provided explicitly, the client will look for the API key.\n",
        "\n",
        "```\n",
        "client = genai.Client()\n",
        "```\n",
        "\n",
        "Or, if you're calling the API through your terminal using `cURL`, you can copy and paste this code to read your key from the environment variable.\n",
        "\n",
        "```\n",
        "curl \"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=$GOOGLE_API_KEY\" \\\n",
        "    -H 'Content-Type: application/json' \\\n",
        "    -X POST \\\n",
        "    -d '{\n",
        "      \"contents\": [{\n",
        "        \"parts\":[{\n",
        "          \"text\": \"Please give me Python code to sort a list.\"\n",
        "        }]\n",
        "      }]\n",
        "    }'\n",
        "```\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CAOKOcax1xZY"
      },
      "source": [
        "## Learning more\n",
        "\n",
        "Now that you know how to manage your API key, you've everything to [get started](./Get_started.ipynb) with Gemini. Check all the [quickstart guides](https://github.com/google-gemini/cookbook/tree/main/quickstarts) from the Cookbook, and in particular the [Get started](./Get_started.ipynb) one."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "name": "Authentication.ipynb",
      "toc_visible": true
    },
    "google": {
      "image_path": "/site-assets/images/share.png",
      "keywords": [
        "examples",
        "googleai",
        "samplecode",
        "python",
        "embed",
        "function"
      ]
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
